#include "radio_manager.h"
#include "../config/config.h"
#include "../serial/serial_manager.h"
#include "../ui/ui_manager.h"
#include "../app/main_app.h"
#include <iostream>
#include <fcntl.h>      // For open()
#include <unistd.h>     // For close()
#include <sys/ioctl.h>
#include <errno.h>      // For errno
#include <string.h>     // For strerror()
#include <termios.h>
#include <thread>
#include <atomic>

// Global variables
extern BaseConfig baseConfig;

// CW port management variables
static bool cw_port_open = false;
static std::string cw_port_name = "";
static int cw_port_fd = -1;
std::atomic<bool> sendThreadRunning(false);
static std::thread sendThreadObj;
static bool forceStopSendThread = false;

void RadioManager::on_radio_config_clicked(GtkWidget *widget, gpointer data) {
    GtkBuilder *builder = GTK_BUILDER(data);
    
    // Update radio configuration from UI
    update_radio_config_from_ui(builder);
    
    // Save configuration to file
    if (!saveBaseConfig("config/config.ini")) {
        std::cerr << "无法保存无线电配置到文件" << std::endl;
    } else {
        std::cout << "成功保存无线电配置到文件" << std::endl;
    }
}

void RadioManager::on_station_config_clicked(GtkWidget *widget, gpointer data) {
    std::cout << "台站配置按钮被点击" << std::endl;
    // Implementation would go here
}

void RadioManager::on_direct_line_config_clicked(GtkWidget *widget, gpointer data) {
    std::cout << "直拍线配置按钮被点击" << std::endl;
    // Implementation would go here
}

void RadioManager::on_cw_config_clicked(GtkWidget *widget, gpointer data) {
    std::cout << "CW配置按钮被点击" << std::endl;
    
    // 检查CW端口是否打开
    if (is_cw_port_open()) {
        // 如果CW端口打开，提示用户先关闭端口
        GtkBuilder *builder = GTK_BUILDER(data);
        GtkWidget *parent_window = gtk_widget_get_toplevel(widget);
        
        GtkWidget *dialog = gtk_message_dialog_new(
            GTK_WINDOW(parent_window),
            GTK_DIALOG_MODAL,
            GTK_MESSAGE_WARNING,
            GTK_BUTTONS_OK,
            "请先关闭CW端口再进行配置"
        );
        
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        
        return; // 直接返回，不显示配置对话框
    }
    
    // 显示CW串口配置对话框
    GtkBuilder *builder = GTK_BUILDER(data);
    GtkWidget *parent_window = gtk_widget_get_toplevel(widget);
    SerialManager::show_serial_config_dialog(parent_window, builder);
}

void RadioManager::save_current_config() {
    // Implementation would go here
}

void RadioManager::update_radio_config_from_ui(GtkBuilder *builder) {
    GtkWidget *band_combo = GTK_WIDGET(gtk_builder_get_object(builder, "band_combo"));
    GtkWidget *frequency_entry = GTK_WIDGET(gtk_builder_get_object(builder, "frequency_entry"));
    GtkWidget *wpm_spin = GTK_WIDGET(gtk_builder_get_object(builder, "wpm_spin"));
    
    if (band_combo) {
        const gchar *band_text = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(band_combo))));
        if (band_text) {
            baseConfig.currentBand = band_text;
        }
    }
    
    if (frequency_entry) {
        const gchar *frequency_text = gtk_entry_get_text(GTK_ENTRY(frequency_entry));
        if (frequency_text) {
            try {
                baseConfig.currentFrequency = std::stod(frequency_text);
            } catch (...) {
                baseConfig.currentFrequency = 14023.0;
            }
        }
    }
    
    if (wpm_spin) {
        baseConfig.wpm = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wpm_spin));
        // Ensure WPM is within valid range
        if (baseConfig.wpm < 5) baseConfig.wpm = 5;
        if (baseConfig.wpm > 40) baseConfig.wpm = 40;
    }
}

bool RadioManager::is_cw_port_open() {
    return cw_port_open;
}

int RadioManager::open_cw_port() {
    // In a real implementation, this would open the actual serial port
    // For now, we'll just set the flag and store the port name
    cw_port_fd = open(baseConfig.port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
    if (cw_port_fd == -1) {
        std::cerr << "无法打开CW串口设备: " << strerror(errno) << std::endl;
        // 提供更具体的错误信息
        if (errno == EACCES) {
            std::cerr << "权限不足，请确保您有访问串口设备的权限。" << std::endl;
            std::cerr << "您可以尝试将用户添加到dialout组：" << std::endl;
            std::cerr << "sudo usermod -a -G dialout $USER" << std::endl;
            std::cerr << "然后注销并重新登录。" << std::endl;
        }
        return -1;
    }
    cw_port_open = true;
    // 设置 DTR 为低电平
    if (set_dtr(cw_port_fd, 0) == -1) {
        std::cerr << "无法设置CW端口DTR为低电平" << std::endl;
        close_cw_port();
        return -1;
    }
    if (set_rts(false) == -1) {
        std::cerr << "无法设置CW端口RTS为低" << std::endl;
        close_cw_port();
        return -1;
    }

    cw_port_name = baseConfig.port;  // Use the same port as the base config
    std::cout << "CW端口已打开: " << cw_port_name << std::endl;
    forceStopSendThread = false;
    return 0;
}

void RadioManager::close_cw_port() {
    // In a real implementation, this would close the actual serial port
    // For now, we'll just reset the flag
    forceStopSendThread = true;
    usleep(40000);
    close(cw_port_fd);
    cw_port_open = false;
    std::cout << "CW端口已关闭" << std::endl;
}

void RadioManager::translateStrToCw(const std::string& str, std::string& cw) {
    std::cout << "translateStrToCw: " << str << std::endl;
    cw.clear();
    for (char c : str) {
        switch (tolower(c))
        {
        case 'a':cw+=".-";break;
        case 'b':cw+="-...";break;
        case 'c':cw+="-.-.";break;
        case 'd':cw+="-..";break;
        case 'e':cw+=".";break;
        case 'f':cw+="..-.";break;
        case 'g':cw+="--.";break;
        case 'h':cw+="....";break;
        case 'i':cw+="..";break;
        case 'j':cw+=".---";break;
        case 'k':cw+="-.-";break;
        case 'l':cw+=".-..";break;
        case 'm':cw+="--";break;
        case 'n':cw+="-.";break;
        case 'o':cw+="---";break;
        case 'p':cw+=".--.";break;
        case 'q':cw+="--.-";break;
        case 'r':cw+=".-.";break;
        case 's':cw+="...";break;
        case 't':cw+="-";break;
        case 'u':cw+="..-";break;
        case 'v':cw+="...-";break;
        case 'w':cw+=".--";break;
        case 'x':cw+="-..-";break;
        case 'y':cw+="-.--";break;
        case 'z':cw+="--..";break;
        case '0':cw+="-----";break;
        case '1':cw+=".----";break;
        case '2':cw+="..---";break;
        case '3':cw+="...--";break;
        case '4':cw+="....-";break;
        case '5':cw+=".....";break;
        case '6':cw+="-....";break;
        case '7':cw+="--...";break;
        case '8':cw+="---..";break;
        case '9':cw+="----.";break;
        case '/':cw+="-..-.";break;
        case '.':cw+=".-.-.-";break;
        case ',':cw+="--..--";break;
        case '?':cw+="..--..";break;
        case '\'':cw+=".-..-.";break;
        case '(':cw+="-.--.";break;
        case ')':cw+="-.--.-";break;
        case '&':cw+=".-...";break;
        case ':':cw+="---...";break;
        case ';':cw+="-.-.-.";break;
        case '=':cw+="-...-";break;
        case '+':cw+=".-.-.";break;
        case '-':cw+="-....-";break;
        case '_':cw+="..--.-";break;
        case '"':cw+=".-..-.";break;
        case '$':cw+="...-..-";break;
        case '@':cw+=".--.-.";break;
        case '{':cw+=".--.-";break;
        case '}':cw+=".--.-";break;
        default:break;
        }
        if(c==' ')
            cw+='A';
        else
            cw+="S";
    }
}

void RadioManager::stopSendThread() {
    forceStopSendThread = true;
}

void RadioManager::send_cw(const std::string& cw) {
    if (!is_cw_port_open()) {
        std::cerr << "CW端口未打开，无法发送CW" << std::endl;
        return;
    }
    forceStopSendThread = false;
    //创建线程执行sendThread函数，传递参数cw
    sendThreadObj = std::thread(&RadioManager::sendThread, cw);
    sendThreadObj.detach();
}

void RadioManager::sendThread(const std::string& cw) {
    if(forceStopSendThread) {
        std::cout << "发送CW线程被强制停止" << std::endl;
        return;
    }
    //如果正在运行，则loop等待上一个线程运行结束
    while(sendThreadRunning) {
        usleep(100000);
    }

    sendThreadRunning = true;
    std::cout << "发送CW: " << cw << std::endl;
    std::string cwstr;
    translateStrToCw(cw, cwstr);
    // 当需要更新UI时，使用g_idle_add
    UpdateUIData* data = new UpdateUIData();
    data->cw = cw;
    data->index = 0; // 当前处理的字符索引
    
    g_idle_add(MainApp::update_qso_memo_callback, data);
    // In a real implementation, this would send the CW to the actual serial port
    // For now, we'll just print the CW to the console
    std::cout << "发送CW: " << cwstr << std::endl;
    int baseTime = 1.2 / baseConfig.wpm * 1000000;
    int ii = 0;
    for(char c : cwstr) {
        //将 QSOMemo 显示的内容对应的字符字体设置为粗体，其他的非粗体
        // 更新当前处理的字符索引
        UpdateUIData* charData = new UpdateUIData();
        charData->cw = cw;
        if(c == 'S'||c=='A') {
            charData->index = ++ii;
        }
        
        g_idle_add(MainApp::update_qso_memo_callback, charData);       


        if(forceStopSendThread) {
            std::cout << "发送CW线程被强制停止" << std::endl;
            break;
        }
        if(c == '.') {
            set_rts(true);
            usleep(baseTime);
            set_rts(false);
            usleep(baseTime);
        } else if(c == '-') {
            set_rts(true);
            usleep(baseTime * 3);
            set_rts(false);
            usleep(baseTime);
        } else if(c == 'A') {
            usleep(baseTime * 3);
        } else if(c=='S') {
            usleep(baseTime);
        }
    }
    sendThreadRunning = false;
}
/**
 * @brief 设置串口 DTR 引脚电平
 * @param fd 已打开的串口文件描述符
 * @param state 电平状态（1=高电平，0=低电平）
 * @return 0=成功，-1=失败
 */
int RadioManager::set_dtr(int fd, int state) {
    int modem_status;  // 存储调制解调器状态（位掩码）

    // 1. 读取当前调制解调器状态（包含 DTR、RTS 等引脚状态）
    if (ioctl(fd, TIOCMGET, &modem_status) == -1) {
        perror("ioctl: 读取调制解调器状态失败");
        return -1;
    }

    // 2. 修改 DTR 对应的位（TIOCM_DTR 位掩码为 0x002）
    if (state) {
        modem_status |= TIOCM_DTR;  // DTR 置 1（高电平）
    } else {
        modem_status &= ~TIOCM_DTR; // DTR 置 0（低电平）
    }

    // 3. 写入新状态，使 DTR 电平生效
    if (ioctl(fd, TIOCMSET, &modem_status) == -1) {
        perror("ioctl: 设置调制解调器状态失败");
        return -1;
    }

    return 0;
}

bool RadioManager::set_rts(bool state) {
    if (!is_cw_port_open()) {
        std::cerr << "CW端口未打开，无法设置RTS" << std::endl;
        return false;
    }
    
    int status;
    
    // 获取当前调制解调器状态
    if (ioctl(cw_port_fd, TIOCMGET, &status) == -1) {
        std::cerr << "获取调制解调器状态失败: " << strerror(errno) << std::endl;
        return false;
    }

    // // 检查 RTS 状态
    // if (status & TIOCM_RTS) {
    //     std::cout << "RTS 信号有效（高电平）" << std::endl;
    // } else {
    //     std::cout << "RTS 信号无效（低电平）" << std::endl;
    // }
    
    // 设置 RTS 状态
    if (state) {
        status |= TIOCM_RTS;  // RTS 置为 1
    } else {
        status &= ~TIOCM_RTS; // RTS 置为 0
    }
    
    // 应用新的状态
    if (ioctl(cw_port_fd, TIOCMSET, &status) == -1) {
        std::cerr << "设置调制解调器状态失败: " << strerror(errno) << std::endl;
        return false;
    }    
    // In a real implementation, this would set the RTS state of the actual serial port
    // For now, we'll just print the state to the console
    // std::cout << "设置RTS为: " << (state ? "高" : "低") << std::endl;
    return true;
}